#include <SGE.h>
using namespace SGE;
#include "fighter.h"
#include "enemy.h"
#include "bullet.h"

//bullets
const int kMaxBullets = 1000;
Bullet bullets[kMaxBullets]; //always choose compliler over preprosessor 
int bulletIndex = 0;

//enemy
const int kMaxEnemies = 100;
enemy Enemies[kMaxEnemies];
int enemyIndex=0;

//explosions
const int kMaxExplosions = 100;
SGE_Emitter explosions[kMaxExplosions];
int explosionIndex=0;

SGE_Sprite background;
SGE_Sound fireSound;
SGE_Sound explosionSound;

float spawnDelay = 0.0f;

//fighter
fighter Fighter;

bool quit = false;

void UpdateGameObjects(float deltaTime)
{
	Fighter.Update(deltaTime);

	for (int i=0; i< kMaxBullets; i++)
	{
		bullets[i].Update(deltaTime);
	}
	for (int i=0; i< kMaxEnemies; i++)
	{
		Enemies[i].Update(deltaTime);
	}
	for (int i=0; i< kMaxExplosions; i++)
	{
		explosions[i].Update(deltaTime);
	}
}

void FireBullets()
{
	if (Input_IsKeyPressed(Keys::SPACE))
	{
		if (!bullets[bulletIndex].IsActive())
		{
			SVector2 pos = Fighter.GetPosition();
			SVector2 vel(0.0f, -500.0f);
			bullets[bulletIndex].Fire(pos, vel); //when incrementing an array for bullets, if the increment exceeds the size of the array, that is called a memory stomp
			bulletIndex= (bulletIndex +1) % kMaxBullets;
		}

		if (!bullets[bulletIndex].IsActive())
		{
			SVector2 pos = Fighter.GetPosition();
			SVector2 vel(100.0f, -500.0f);
			bullets[bulletIndex].Fire(pos, vel); //when incrementing an array for bullets, if the increment exceeds the size of the array, that is called a memory stomp
			bulletIndex= (bulletIndex +1) % kMaxBullets;
		}

		if (!bullets[bulletIndex].IsActive())
		{
			SVector2 pos = Fighter.GetPosition();
			SVector2 vel(-100.0f, -500.0f);
			bullets[bulletIndex].Fire(pos, vel); //when incrementing an array for bullets, if the increment exceeds the size of the array, that is called a memory stomp
			bulletIndex= (bulletIndex +1) % kMaxBullets;
		}
		fireSound.Play();
	}

	

}

void SpawnEnemies(float deltaTime)
{
	spawnDelay -= deltaTime;
	if (spawnDelay <= 0.0f)
	{
		//time to spawn
		if (!Enemies[enemyIndex].IsActive())
		{
			const int kWinWidth = IniFile_GetInt("WinWidth", 800);
			const float posX = kWinWidth * RandomFloat(0.1f, 0.9f);
			const float posY = -100.0f;
			Enemies[enemyIndex].Spawn(SVector2(posX, posY));
			enemyIndex = (enemyIndex + 1) % kMaxEnemies; 

			//reset Delay
			spawnDelay = RandomFloat(0.1f, 1.0f);
		}

	}
}

void CheckCollision()
{
	for (int e=0; e < kMaxEnemies; e++)
	{
		if (Enemies [e].IsActive())
		{
			for (int b = 0; b < kMaxBullets; b++)
			{
				if (bullets[b].IsActive())
				{
					SCircle eCircle = Enemies[e].GetBoundingCircle();
					SCircle bCircle = bullets[b].GetBoundingCircle();
					float xDiff = eCircle.center.x - bCircle.center.x;
					float yDiff = eCircle.center.y - bCircle.center.y;
					float dist = sqrt(xDiff * xDiff + yDiff * yDiff);
					float radii = eCircle.radius + bCircle.radius;

					if (dist <=radii)
					{
						Enemies[e].Kill();
						bullets[b].Kill();

						explosions[explosionIndex].SetPosition(eCircle.center);
						explosions[explosionIndex].Start(100.0f, true);
						explosionIndex=(explosionIndex+1) % kMaxExplosions;
						explosionSound.Play();
						break;
					}

				}

			}

		}

	}
}

void SGE_Initialize()
{
	Fighter.Load();
	const int kWinWidth = IniFile_GetInt("WinWidth", 800);
	const int kWinHeight = IniFile_GetInt("WinHeight", 600);
	SVector2 offset( kWinWidth * 0.5f,kWinHeight  * 0.9f);
	Fighter.SetPosition(offset);

	for (int i=0; i< kMaxBullets; i++)
	{
		bullets[i].Load();
	}

	for (int i=0; i< kMaxEnemies; i++)
	{
		Enemies[i].Load();
	}
	for (int i=0; i< kMaxExplosions; i++)
	{
		explosions[i].Load("explosion.txt");
	}

	background.Load("space.jpg");
	fireSound.Load("photongun1.wav");
	explosionSound.Load("explosion.wav");
}

void SGE_Terminate()
{
	Fighter.Unload();
	for (int i=0; i< kMaxBullets; i++)
	{
		bullets[i].Unload();
	}
	for (int i=0; i< kMaxEnemies; i++)
	{
		Enemies[i].Unload();
	}
	for (int i=0; i< kMaxExplosions; i++)
	{
		explosions[i].Unload();
	}

	background.Unload();
	fireSound.Unload();
	explosionSound.Unload();
}

bool SGE_Update(float deltaTime)
{
	UpdateGameObjects(deltaTime);
	FireBullets();
	SpawnEnemies(deltaTime);
	CheckCollision();

	if (Input_IsKeyPressed(Keys::ESCAPE))
	{
		quit = true;
	}
	return quit;

	/*pointer arithmatics:
	int *ptr=80;
	int num=80;
	ptr++, ptr=84; this is becuase when its an int pointer, it holds 4 bytes, so it increments four bytes from original position
	num++= 81;
	*/
}

void SGE_Render()
{
	background.Render();

	for (int i=0; i< kMaxBullets; i++)
	{
		bullets[i].Render();
	}

	for (int i=0; i< kMaxEnemies; i++)
	{
		Enemies[i].Render();
	}

	Fighter.Render();

	for (int i=0; i< kMaxExplosions; i++)
	{
		explosions[i].Render(true);
	}
}

